package com.lightsaber.trade.cloth.service.category.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.lightsaber.trade.core.entity.AuditedObject;
import com.lightsaber.trade.core.entity.BaseEntity;
import com.lightsaber.trade.cloth.dao.category.CategoryNodeDao;
import com.lightsaber.trade.cloth.dao.category.CategoryPlannerDao;
import com.lightsaber.trade.cloth.entity.category.CategoryNode;
import com.lightsaber.trade.cloth.entity.category.CategoryOwner;
import com.lightsaber.trade.cloth.entity.category.CategoryPlanner;
import com.lightsaber.trade.cloth.service.category.CategoryPlannerService;

@Component
@Transactional
public class CategoryPlannerServiceImpl implements CategoryPlannerService {
    @Autowired
    CategoryPlannerDao categoryPlannerDao;
    @Autowired
    CategoryNodeDao categoryNodeDao;

    @Override
    public void create(final CategoryPlanner categoryPlanner) {
        categoryPlannerDao.save(categoryPlanner);

    }

    @Override
    public CategoryOwner findById(final String id) {

        return null;
    }

    @Override
    public void deleteById(final String id) {
        categoryPlannerDao.delete(id);

    }

    @Override
    public void deleteByCategoryNodeId(final String categoryNodeId) {
        categoryPlannerDao.deleteByCategoryNodeId(categoryNodeId);

    }

    @Override
    public void saveByCategoryNodeAndRoleCodes(final CategoryNode categoryNode,
            final List<String> roleCodes) {
        CategoryPlanner categoryPlanner = new CategoryPlanner();
        categoryPlanner.setCategoryNode(categoryNode);
        for (String roleCode : roleCodes) {
            categoryPlanner.setRoleCode(roleCode);
            categoryPlannerDao.save(categoryPlanner);
        }

    }

    @Override
    public void saveByCategoryNodeAndRoleCodes(final String categoryNodeId,
            final List<String> roleCodes) {
        // 1.delete category node all relation role
        deleteByCategoryNodeId(categoryNodeId);
        CategoryNode categoryNode = categoryNodeDao.load(categoryNodeId);
        if (roleCodes == null) {
            deleteSubNodePlanners(categoryNode);
            return;
        }

        for (String roleCode : roleCodes) {
            CategoryPlanner categoryPlanner = new CategoryPlanner();
            categoryPlanner.setCategoryNode(categoryNode);
            categoryPlanner.setRoleCode(roleCode);
            categoryPlannerDao.save(categoryPlanner);
        }
        copyPlanners(categoryNode, roleCodes);
    }

    public void copyPlanners(final CategoryNode currentNode, final List<String> roleCodes) {
        List<CategoryNode> children = currentNode.getChildren();
        if (!children.isEmpty()) {
            for (int i = 0; i < children.size(); i++) {
                CategoryNode child = children.get(i);
                saveByCategoryNodeAndRoleCodes(child.getId(), roleCodes);
                if (!child.getChildren().isEmpty()) {
                    copyPlanners(child, roleCodes);
                }
            }
        }
    }

    public void deleteSubNodePlanners(final CategoryNode currentNode) {
        List<CategoryNode> children = currentNode.getChildren();
        if (!children.isEmpty()) {
            for (int i = 0; i < children.size(); i++) {
                CategoryNode child = children.get(i);
                deleteByCategoryNodeId(child.getId());
                if (!child.getChildren().isEmpty()) {
                    deleteSubNodePlanners(child);
                }
            }
        }
    }

    @Override
    public List<String> getRoleCodesByCategoryNodeId(final String categoryNodeId) {
        List<String> roleCodes = new ArrayList<String>();
        List<CategoryPlanner> categoryPlanners = categoryPlannerDao.findBy("categoryNode.id",
                categoryNodeId);
        for (CategoryPlanner categoryPlanner : categoryPlanners) {
            roleCodes.add(categoryPlanner.getRoleCode());
        }
        return roleCodes;
    }

    @Override
    public List<CategoryPlanner> findByCategoryNodeId(final String categoryNodeId) {
        return categoryPlannerDao.findByCategoryNodeId(categoryNodeId);
    }

    @Override
    public void inheritPlanners(final CategoryNode categoryNode) {
        CategoryNode parent = categoryNode.getParent();
        List<CategoryPlanner> list = parent.getCategoryPlanners();
        for (CategoryPlanner old : list) {
            CategoryPlanner newPlanner = new CategoryPlanner();
            BeanUtils.copyProperties(old, newPlanner, new String[] { BaseEntity.ID, "categoryNode",
                    AuditedObject.CREATED_BY, AuditedObject.CREATED_DATE });
            newPlanner.setCategoryNode(categoryNode);
            categoryPlannerDao.save(newPlanner);
        }
    }

    @Override
    public void copyPlannersByCategoryNode(final CategoryNode oldNode, final CategoryNode newNode) {
        List<CategoryPlanner> plannerList = oldNode.getCategoryPlanners();
        if (plannerList.isEmpty()) {
            return;
        }
        for (CategoryPlanner old : plannerList) {
            CategoryPlanner newPlanner = new CategoryPlanner();
            newPlanner.setCategoryNode(newNode);
            newPlanner.setRoleCode(old.getRoleCode());
            categoryPlannerDao.save(newPlanner);
        }
    }

}
